home *** CD-ROM | disk | FTP | other *** search
Text File | 1989-06-26 | 5.5 KB | 164 lines | [TEXT/GEOL] |
- Item 3002379 4-May-89 23:06
-
- From: CH0095 CH DEV PEMD Group
-
- To: MACAPP.TECH$ MACAPP Tech
-
- Sub: More on "Later Versions"
-
- Hi Everyone,
-
- Thanks for the great communal response to the "Later Versions" questions. It's
- still not entirely clear to me.
-
- Assume that DoRead/doWrite use
- GraphRecord =
- DataArray: Array[1...kMaxPoints] of String[kMaxDataLength};
- PredictArray: Array[1...kMaxPoints] of Boolean;
- AreaName: String[kMaxAreaNameLength];
- AreaName: String[kMaxAbbrevLength];
- PrtedictInfo: String[kMaxPredictInfoLength];
- End; {all identifiers begiining with "k" are constants defined in the
- CONST section of ourApp.p.}
-
- There is a TGraphObject that corresponds to the GraphRecord. It has the
- identical data structure plus methods. At read time the fields of the
- GraphRecords are read into the fields of GraphObjects. If different
- GraphRecords are defined for different values of the "k" constants (e.g.
- GraphRecord1, GraphRecord2, etc.) then there must be correspondingly different
- definitions for TGraphObjects (e.g. TGraphObject1, TGraphObject2, etc.).
-
- Subsequent code must then always consider which GraphObject definition is to be
- used. For example, whenever a New call is made there must be some sort of
- conditional statement determining the type of GraphObject to make, and then all
- following code must be duplicated for each type of GraphObject.
-
- Am I off? If accurate such a strategy would result is extremely thick and
- ponderous code. There seems to be two problems. All would be straight forward
- if Pascal allowed dynamic arrays and second it would also work if the
- GraphRecord and GraphObject definitions could be kept seperate.
-
- Below is a link from MacDTS keeping the two definitions seperate. I'm not yet
- clear on how to implement it. The first problem is that I don't understand an
- array defintion as: Array [0..0] of INTEGER; how can an array dimension have
- no length? Is his Arraytemplate an indirect way to establish dynamic arrays in
- Pascal?
-
- Am I thinking about all this in a funny way? Wiil really appreciate whatever
- guidance any of you have.
-
- Regards,
- Ernie
-
-
- _____________________________________________________________________________
- The only clean way to make your file formats the same while
- your internal data structures change is to seperate the
- file format data structures from the class structures.
-
- You should define a set of RECORD templates for your file
- format, and have your objects write their data in the
- format of the templates. This means that you have to do
- more programming work, but it does give you some valuable
- independence from your object definitions. Whatever file
- format you do pick, it should be smart enough to deal with
- variable length data.
-
- There isn't any way that Pascal (or C) can be made to
- understand dynamic, variably sized data structures. The
- language just doesn't work that way.
-
- Here is a small example. I'm just typing this in out of my
- head, so there will probably be a few typos and type
- checking errors, but you get the idea. Lets say I have a
- class, TMyData:
-
- CONST
- kNumPoints = 24;
-
- TYPE
- TMyData = OBJECT(TObject)
- fMyArray : ARRAY[1..kNumPoints] OF INTEGER;
- { all the usual methods...}
- { our I/O methods, called by our subclass of TDocument...}
- TMyData.DoRead(aRefNum: INTEGER);
- TMyData.DoWrite(aRefNum: INTEGER);
- END;
-
- { Template for our array type }
- MyArrayTemplate = RECORD
- arraySize : INTEGER;
- arrayData : ARRAY [0..0] OF INTEGER;
- END;
- MyArrayTemplatePtr = ^MyArrayTemplate;
- MyArrayTemplateHdl = ^MyArrayTemplatePtr;
-
- Now, in my DoWrite method, I do this:
-
- PROCEDURE TMyData.DoWrite(aRefNum:INTEGER);
- VAR
- arrTmpl : MyArrayTemplateHdl;
- i, nElems : INTEGER;
- tmplSize : LONGINT;
- BEGIN
- { allocate a template of correct size }
- tmplSize := SIZEOF(MyArrayTemplate) + (SIZEOF(INTEGER) * kNumPoints);
- arrTmpl = NewHandle(tmplSize);
- FailNIL(arrTmpl);
- { fill in the template }
- arrTmpl^^.arraySize := kNumPoints;
- {$PUSH} {$R-}
- FOR i := 0 to kNumPoints-1 DO
- arrTmpl^^.arrayData[i] := fMyArray[i+1];
- {$POP}
- { Write size of array }
- nElems := kNumPoints;
- i := SIZEOF(INTEGER);
- FailOSErr(FSWrite(aRefNum,i,Ptr(@nElems));
- { Write contents of array }
- FailOSErr(FSWrite(aRefNum,tmplSize,Ptr(arrTmpl^));
- END;
-
- Now, DoRead has to read in a data structure, which may be bigger than
- the current size...
-
- PROCEDURE TMyData.DoRead(aRefNum:INTEGER);
- VAR
- arrTmpl : MyArrayTemplateHdl;
- i,cnt : INTEGER;
- tmplSize, nElems : INTEGER;
- BEGIN
- { Read num elems in array }
- cnt := SIZEOF(INTEGER);
- FailOSErr(FSRead(aRefNum,cnt,Ptr(@nElems)));
- { allocate a template big enough to read entire array }
- tmplSize := SIZEOF(MyArrayTemplate) + (SIZEOF(INTEGER) * nElems);
- arrTmpl = NewHandle(tmplSize);
- FailNIL(arrTmpl);
- { Read array into template }
- cnt := SIZEOF(INTEGER) * nElems;
- FailOSErr(FSRead(aRefNum,cnt,Ptr(@arrTmpl^^.arrayData)));
- { now, copy the array into our object }
- cnt := MIN(kNumPoints,nElems); { don't try and copy more than we got }
- {$PUSH} {$R-}
- FOR i := 0 TO cnt-1 DO
- fMyArray[i+1] := arrTmpl^^.arrayData[i];
- { If we don't have enough data to fill object array, pad with zeros }
- IF nElems < kNumPoints THEN
- FOR i := cnt TO kNumPoints DO
- fMyArray[i] := 0;
- { NOTE: we truncate array if it was too big... }
- {$POP}
- END;
-
- Have fun,
-
- Andrew Shebanow
- MacDTS
- Apple Computer, Inc.
-
-
-
-
-
-